use std::{env, sync::OnceLock};

use agent::hunyuan::init_agent;
use common::{compose::{make_empty_ctx, CallBox, CallCore, Composer, FError, ListHandler}, tools::{get_dir_file_paths, get_file_content, write_file_content}};

static TRANS_AGENT: OnceLock<CallBox<String, String>> = OnceLock::new();

pub fn get_trans_agent() -> &'static CallBox<'static, String, String> {
    TRANS_AGENT.get_or_init(move|| {
        let api_key = env::var("HUNYUNA_API_KEY").expect("HUNYUNA_API_KEY not found");
        // Convert to a 'static str by leaking memory (acceptable for this singleton pattern)
        let api_key_static = Box::leak(api_key.into_boxed_str());
        // 初始化Agent
        let system = r#"
请将文本内容专业地翻译为中文，要求：

1. 保持原文语义完整性和逻辑结构
2. 使用书面正式语体，避免口语化表达
3. 对专业术语进行准确转换
4. 保留原始段落格式和标点规范
5. 文化意象做本土化适配处理
6. 完成初稿后进行两次交叉校验，确保翻译质量
"#;
        // 初始化Agent
        let agent = init_agent(system, api_key_static);
        agent
    })
}

pub async fn trans_file(base_dir: &str, file_path: &str, output_dir: &str) -> Result<(), FError> {
    let content = get_file_content(&format!("{}/{}", base_dir, file_path))?;
    let agent = get_trans_agent();
    let res = agent.run(content, make_empty_ctx()).await?;
    write_file_content(&format!("{}/{}", output_dir, file_path), &res)?;
    Ok(())
}

pub async fn trans_dir(input_dir: &str, output_dir: &str) -> Result<(), FError> {
    // 获取input_dir下所有文件的相对路径
    let paths = get_dir_file_paths(input_dir)?;
    let callbox = Composer::from_fn(async move |path: String| {
        println!("trans_file: {}", path);
        trans_file(input_dir, &path, output_dir).await
    });
    let list_handler = ListHandler::new(5, callbox);
    let _rs = list_handler.run(paths, make_empty_ctx()).await?;
    Ok(())
}


#[cfg(test)]
mod tests {
    use super::*;

    #[tokio::test]
    async fn test_trans_dir() {
        dotenvy::from_path("../../.env").ok();
        let input_dir = "E:\\project\\opensource\\docsite\\docs-src\\0.6\\src\\reference";
        let output_dir = "d:\\test\\reference";
        trans_dir(input_dir, output_dir).await.unwrap();
        assert!(true);
    }

    #[tokio::test]
    async fn test_trans_file() {
        dotenvy::from_path("../../.env").ok();
        let input_dir = "E:\\project\\yesdoc\\dioxus\\docs\\en\\learn\\02_guide";
        let output_dir = "E:\\project\\yesdoc\\dioxus\\docs\\zh\\learn\\02_guide"; 
        let file_path = "index.md";
        trans_file(input_dir, file_path, output_dir).await.unwrap();
        assert!(true);
    }

}